/**
 * 获取组件所需数据
 */
import { ref } from "vue";
import { defineStore } from "pinia";
import {
  apiGetIndexPostData,
  apiGetIndexPostDatas,
  apiGetImgData,
  apiGetCatData,
  apiGetCatPostData,
  apiGetSearchData,
  apiGetPostData,
  apiGetConfigData,
} from "@/api/api";
import {
  GetOptionData,
  GetCatData,
  IndexShowData,
  GetOption,
} from "@/api/interface";

import imgUrls from "@/assets/images/error-404-bg.png";

interface PostData {
  [key: number]: any;
}
interface AItem {
  id: number;
  data: any;
}

interface A {
  [key: number]: AItem;
}

interface CItem {
  id: number;
  data: any;
}

//interface C extends Array<CItem> {}
// 创建 store
const useGetData = defineStore("get", {
  // 定义状态：一个函数，返回一个对象
  state: () => ({
    //批量发起GET请求

    //简单文章数组
    postEasyData: {} as PostData,
    //文章详情数组
    postData: {} as PostData,
    //配置
    option: <GetOptionData>{},
    //存档页用
    archive: {
      cat: [{}],
      year: [{}],
      month: [{}],
    },
  }),

  // 定义 getters，等同于组件的计算属性
  getters: {
    // getter 函数接收 state 作为参数，推荐使用箭头函数
  },

  // 定义 actions，有同步和异步两种类型
  actions: {
    /**
     * 处理图片
     * @param 图片ID
     * @returns 对象
     */
    async handleImg(id: number) {
      // 定义默认返回值
      const obj: IndexShowData["image"] = {
        url: "",
        caption: "",
        details: {
          width: 0,
          height: 0,
          filesize: 0,
        },
      };

      try {
        //拿到图片信息
        const res = await apiGetImgData({ include: id });

        //是否有图片
        if (res.length === 0) {
          //没有图片就给默认值
          obj.url = imgUrls;
        } else {
          const {
            guid: { rendered: url },
            caption: { rendered: caption },
            media_details: { width, height, filesize, sizes },
          } = res[0];

          obj.url = url;
          obj.caption = caption;
          obj.details.width = width;
          obj.details.height = height;
          obj.details.filesize = filesize;
          obj.details.sizes = sizes;
        }
      } catch (e) {
        console.error(e);
      }

      return obj;
    },
    //处理时间
    handleTime(time: string) {
      const dateObject = new Date(time);
      const year = dateObject.getFullYear(); // 年份
      const month = dateObject.getMonth() + 1; // 月份，需要加 1
      const day = dateObject.getDate(); // 日

      const formattedDateString = `${year} 年 ${month} 月 ${day} 日`;
      return formattedDateString;
    },

    /**
     * 对传入的原始数据进行处理后输出
     * @param obj  对象
     * @returns  对象
     */
    async handleObj(obj: any) {
      const {
        id,
        date,
        link,
        title,
        content,
        excerpt,
        featured_media,
        categories,
      } = obj;
      //处理图片和分类
      const promises = [];
      //图片请求
      const imgGet = this.handleImg(featured_media);
      promises.push(imgGet);
      //分类请求

      //只取前三个分类
      for (const item of categories.slice(0, 3)) {
        const params = {
          _fields: "id,count,name,link",
          include: item,
        };
        const catObj = apiGetCatData(params);
        promises.push(catObj);
      }

      //发出请求
      const meatData = await Promise.all(promises);
      const catData = meatData.slice(1, 3) as unknown as GetCatData[];
      const objects = catData.flatMap((subArray) => subArray);

      //使用对象解构提高代码可读性
      const data: IndexShowData = {
        id,
        date: this.handleTime(date),
        link: link,
        title: title.rendered,
        content: content ? content.rendered : "",
        excerpt: excerpt ? excerpt.rendered : "",
        image: meatData[0] as IndexShowData["image"],
        cat: objects,
      };

      return data;
    },

    /**
     * 获取最新的11篇文章ID
     * @returns 数组
     */
    GetLatestData(): Promise<number[]> {
      return new Promise((resolve, reject) => {
        apiGetIndexPostData({ per_page: 11 })
          .then((data) => {
            const arr = data.map((item: { id: any }) => item.id);
            resolve(arr);
          })
          .catch((error) => {
            console.log(error);
            resolve([]);
          });
      });
    },

    //发出请求
    async getPagePostIds(
      per: number,
      page: number,
      cat?: number,
      year?: number,
      month?: number
    ) {
      const params: any = {
        per_page: per,
        page,
      };

      if (cat) params.categories = cat;

      const currentYear = new Date().getFullYear(); //当前年份

      if (year) {
        let startDate = new Date(year, 0, 1);
        let endDate = new Date(year, 12, 1);
        if (month) {
          startDate = new Date(year, month - 1, 1);
          endDate = new Date(year, month, 1);
        }
        params.after = `${startDate.toISOString().split("T")[0]}T00:00:00Z`;
        params.before = `${endDate.toISOString().split("T")[0]}T00:00:00Z`;
      } else if (month) {
        let startDate = new Date(currentYear, month - 1, 1);
        let endDate = new Date(currentYear, month, 1);
        params.after = `${startDate.toISOString().split("T")[0]}T00:00:00Z`;
        params.before = `${endDate.toISOString().split("T")[0]}T00:00:00Z`;
      }

 

      const { headers, data } = await apiGetIndexPostDatas(params);

      return {
        page: headers["x-wp-totalpages"],
        data,
      };
    },

    /**
     * 提供配置，返回处理后的文章信息
     * @param id 文章ID
     * @returns 对象
     */
    GetPostData(params: {}): Promise<IndexShowData> {
      return new Promise((resolve, reject) => {
        apiGetPostData(params)
          .then((res) => {
            const result = this.handleObj(res[0]);
            resolve(result);
          })
          .catch((error) => {
            console.log(error);
            reject(error); // 可以将 error 值传递给外层的 catch 处理
          });
      });
    },

    /**
     * 接收id数组，返回简易文章内容Promise
     * @param arr 文章ID数组
     * @returns 数组
     */
    GetHandlePromisesArr(arr: Array<number>) {
      //临时存储请求
      const promises = [];
      for (let i = 0; i < arr.length; i++) {
        const params = {
          _fields: "categories,title,link,date,featured_media,author,id",
          include: arr[i],
        };
        promises.push(this.GetPostData(params));
      }
      const result = Promise.all(promises);
      return result;
    },

    //接收文章ID，返回文章简略信息Promise
    getPostEasyData(id: number) {
      const params = {
        _fields: "categories,title,link,date,featured_media,author,id",
        include: id,
      };
      const result = this.GetPostData(params);
      return result;
    },

    //接收文章ID，返回文章详情Promise
    getPostData(id: number) {
      const params = {
        _fields:
          "categories,title,link,date,featured_media,author,id,content,excerpt",
        include: id,
      };
      const result = this.GetPostData(params);
      return result;
    },

    //获取指定分类的分类信息
    getCatData(id: number) {
      const params = {
        include: id,
        _fields: "id,count,name,link",
      };

      const data = apiGetCatData(params);

      return data;
    },

    /**
     * 获取指定分类下的文章id
     * @param id 分类ID
     * @param per 获取文章数
     * @returns  文章ID数组
     */
    async GetCatPostData(id: number, per: number) {
      try {
        const data = await apiGetCatPostData({
          categories: id, //获取指定分类下的文章
          orderby: "id", //按文章ID顺序排序
          per_page: per, //获取最近的指定篇数文章
        });

        const result = data.map((obj: { id: number }) => obj.id);

        return result;
      } catch (error) {
        console.log(error);
        return [];
      }
    },

    /**
     * 获取指定分类下的文章信息
     * @param id 分类ID
     * @param per 获取文章数
     * @returns 展示用数组
     */
    async apiGetCatDataShow(id: number, per: number) {
      //获取分类下的文章ID数组
      const arr = await this.GetCatPostData(id, per);
      //先查询ID数组，查不到就获取
      const data = this.packageEasyPostData(arr);
      return data;
    },

    /**
     * 搜索用
     * @param q 搜索词
     * @returns 返回搜索到的数组
     */
    async GetSearchData(q: string) {
      try {
        //拿到文章ID数组
        const data = await apiGetSearchData({ search: q, per_page: 6 });
        //将解雇处理成数组
        const arr = data.map((item) => item.id);

        const result = this.packageEasyPostData(arr);
        return result;
      } catch (error) {
        console.log(error);
        return [];
      }
    },

    //获取配置信息并存储
    //先判断pinia中有没有值，有值不处理，没有值就请求后存在pinia中，
    GetOptionData() {
      //处理函数
      const getOptionObj = (data: GetOption) => {
        const obj = {
          index: {
            // 首页幻灯片
            tone: {
              carousel: data.comm_h5_index_tone,
              //更多按钮
              category: data.comm_h5_index_tone_cat,
            },
            // 首页更多按钮
            more: {
              category: data.comm_h5_index_category,
            },
          },
          single: {
            // 文章页 - 联系
            contact: {
              title: data.comm_h5_single_contact_title,
              content: [
                {
                  title: data.comm_h5_single_contact_one_title,
                  content: data.comm_h5_single_contact_one_content,
                },
                {
                  title: data.comm_h5_single_contact_two_title,
                  content: data.comm_h5_single_contact_two_content,
                },
              ],
            },
            // 文章页 - 品牌
            featured: {
              link: data.comm_h5_singel_featured_link,
              logo: data.comm_h5_singel_featured_logo,
              msg: data.comm_h5_singel_featured_msg,
            },
          },
        };
        return obj;
      };

      //开始返回

      // 判断 pinia 中是否有值
      if (Object.values(this.option).length > 0) {
        // 如果有值，直接返回 pinia 中的数据
      } else {
        // 如果 pinia 中没有值，调用 apiGetConfigData 获取数据
        apiGetConfigData({}).then((res) => {
          const data = getOptionObj(res);
          this.option = data; // 将获取到的数据存入 pinia 中
        });
      }
    },

    /**
     * 传入文章数组，返回详细信息，若pinna中存有，则从pinna中返回
     * b:结果数组中的对象类型
     * @param piniaData 存储数据的对象类型，使用数字类型的索引
     * @param idArr 包含 ID 属性的数组类型
     * @param get 获取文章内容的方法
     * @returns
     */
    async getCFromA(
      piniaData: A,
      idArr: number[],
      get: (id: number) => Promise<any>
    ): Promise<any[]> {
      // 使用 Promise.all() 并行获取缺失的数据
      const getPromises: Promise<AItem>[] = [];
      const c = [];
      for (const id of idArr) {
        let data = piniaData[id];
        if (!data) {
          // 如果缓存中没有数据项，则添加 Promise 到 getPromises 数组中
          const promise = get(id).then((data) => {
            const aItem: AItem = { id, data };
            piniaData[id] = aItem;
            return aItem;
          });
          getPromises.push(promise);
        } else {
          // 如果缓存中有数据项，则直接添加到结果数组中
          const cItem: CItem = { id: data.id, data: data.data };
          c.push(cItem);
          console.log("使用了缓存值");
        }
      }

      // 等待 Promise.all() 返回所有缺失的数据
      const retrievedItems = await Promise.all(getPromises);

      // 将新获取的数据项添加到结果数组中
      retrievedItems.forEach((item) => {
        const cItem: CItem = { id: item.id, data: item.data };
        c.push(cItem);
      });

      return c.map((item) => item.data);
    },

    //封装，获取文章简单内容（不拿副标题和文章内容）
    /**
     * 封装 - 获取文章简单内容
     * @param arr 文章ID数组
     * @returns 详细内容数组
     */
    packageEasyPostData(arr: Array<number>) {
      const data = this.getCFromA(this.postEasyData, arr, this.getPostEasyData);
      return data;
    },

    /**
     * 封装 - 获取文章详细内容
     * @param arr 文章ID数组
     * @returns 详细内容数组
     */
    packagePostData(arr: Array<number>) {
      const data = this.getCFromA(this.postData, arr, this.getPostData);
      return data;
    },

    /**
     * 根据分类ID推荐相关文章
     * @param arr 分类ID数组
     * @param id 本文ID
     * @param num 推荐的文章数
     * @returns 推荐的文章信息数组对象
     */
    async GetInterrelatedData(arr: Array<number>, id: number, num: number) {
      //通过分类ID获取分类中的文章ID
      const arrData = await Promise.all(
        arr.map((num: number) => this.GetCatPostData(num, 6))
      );
      //二维数组变一维数组 - 文章可能有多个分类，此处有多个数组，
      const arrs = arrData.flat();
      //数组去重
      const uniqueArr = [...new Set(arrs)];
      //去除本文ID
      const finalArr = uniqueArr.filter((item) => item !== id);
      //打乱数组
      const disorderArr = finalArr.sort(() => Math.random() - 0.5);

      //取前三，ID数组
      const selectArr = disorderArr.slice(0, num);

      //取结果
      if (typeof selectArr !== "undefined") {
        //先从pinia中找值
        const data = this.packagePostData(selectArr);
        return data;
      }
    },

    //传入数组处理成请求 - 自定义接口取值
    //async GetHandleIdArr(arr: Array<number>) {
    //  try {
    //    //临时存储请求
    //    const promises = [];
    //    for (let i = 0; i < arr.length; i++) {
    //      promises.push(apiGetPostIdData({}, arr[i]));
    //    }
    //    const result = await Promise.all(promises);
    //    return result;
    //  } catch (error) {
    //    console.log(error);
    //    return [];
    //  }
    //},
    //将值存入single
    //setSingle(post: IndexShowData) {
    //  //先检查pinia中有没有该对象
    //  const pinia = this.get.single;
    //  const isObjExist = (arr: Array<IndexShowData>, obj: IndexShowData) => {
    //    return arr.some((item) => item.id === obj.id);
    //  };
    //  if (!isObjExist(pinia, post)) {
    //    pinia.push(post);
    //    console.log("已存数据进Pinia");
    //  }
    //
    //  console.log("当前Pinia中存储的值");
    //  console.log(this.get.single);
    //},

    //获取第一篇文章的相关信息，从而获取网站的第一篇文章发布时间,生成倒序时间列表
    async getPostFirstDate() {
      const params = {
        _fields: "id,date", //筛选需要的信息
        per_page: 1, // 获取一篇文章
        orderby: "date", // 按照发布日期排序
        order: "asc", // 升序排序
      };
      const data = await apiGetPostData(params);
      const result = data[0].date;

      const arr = []; // 初始化一个数组，存储数据
      const old = result.substr(0, 4); // 取出前4个字符，即年份部分 - 初始年份
      const endYear = new Date().getFullYear(); // 当前年份
      for (let i = old; i <= endYear; i++) {
        arr.push({
          value: String(i.toString()),
          label: String(i.toString()),
          disabled: false,
        });
      }
      arr.reverse().unshift({
        value: "all",
        label: "全部年份",
        disabled: false,
      }); // 在数组头部添加新的对象
      this.archive.year = arr;

      //return arr;
    },

    //获取分类列表组成对象的数组，排除子分类和文章为0的分类
    async getCatList() {
      const params = {
        _fields: "id,name,count,parent", //筛选需要的信息
        per_page: 99,
      };
      const data = await apiGetCatData(params);

      const categories: { id: any; name: any; count: any }[] = []; // 用于存放分类信息的数组
      // 处理分类数据
      data.forEach(
        (item: { count: number; parent: number; id: number; name: string }) => {
          if (item.count > 0 && item.parent === 0) {
            categories.push({
              id: item.id,
              name: item.name,
              count: item.count,
            });
          }
        }
      );

      // 按照文章数从大到小进行排序

      categories.sort((a, b) => b.count - a.count);
      const arr = categories.map((item) => {
        return {
          value: item.id as string,
          label: item.name as string,
          disabled: false,
        };
      });
      arr.unshift({
        value: "all",
        label: "全部分类",
        disabled: false,
      });
      this.archive.cat = arr;
    

      
    },

    //end
  },
});

export default useGetData;
